package com.orderplus.opshop.common.util;

import cn.hutool.core.util.StrUtil;
import com.google.gson.Gson;
import com.orderplus.opshop.common.util.date.DateUtil;
import org.apache.commons.beanutils.BeanMap;
import org.apache.commons.beanutils.BeanUtils;
import org.apache.commons.beanutils.ConvertUtils;
import org.apache.commons.beanutils.converters.DateConverter;
import org.apache.commons.beanutils.converters.SqlDateConverter;
import org.apache.commons.beanutils.converters.SqlTimestampConverter;

import java.beans.BeanInfo;
import java.beans.IntrospectionException;
import java.beans.Introspector;
import java.beans.PropertyDescriptor;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;


/**
 * Title: Map的处理类
 * Description: 手动生成
 * Company: Copyright @ 2019 OrderPlus 版权所有
 *
 * @version 1.0 初稿
 * @author: 麦豪俊
 * @date: 2016-5-17 17:59:58
 */
public class MapUtil {
	public static Map<String, String> convertMapSubType(Map<String, Object> param) {
		Map<String, String> result = new HashMap<String, String>();
		Set<Entry<String, Object>> entrySet = param.entrySet();
		for (Iterator<Entry<String, Object>> iter = entrySet.iterator(); iter.hasNext(); ) {
			Entry<String, Object> entry = iter.next();
			String key = entry.getKey();
			Object value = entry.getValue();
			result.put(key, ValueUtil.toStr(value));
		}
		return result;
	}

	/**
	 * 将一个 Map 对象转化为一个 JavaBean
	 *
	 * @param type 要转化的类型
	 * @param map  包含属性值的 map
	 * @return 转化出来的 JavaBean 对象
	 * @throws IntrospectionException    如果分析类属性失败
	 * @throws IllegalAccessException    如果实例化 JavaBean 失败
	 * @throws InstantiationException    如果实例化 JavaBean 失败
	 * @throws InvocationTargetException 如果调用属性的 setter 方法失败
	 */
	@SuppressWarnings({"rawtypes"})
	public static Object convertMap(Class type, Map map) throws IntrospectionException, InstantiationException, IllegalAccessException {
		BeanInfo beanInfo = Introspector.getBeanInfo(type); // 获取类属性
		Object obj = type.newInstance(); // 创建 JavaBean 对象

		// 给 JavaBean 对象的属性赋值
		PropertyDescriptor[] propertyDescriptors = beanInfo.getPropertyDescriptors();

//		System.out.println("map all:"+map);
		for (int i = 0; i < propertyDescriptors.length; i++) {
			PropertyDescriptor descriptor = propertyDescriptors[i];
			String propertyName = descriptor.getName();

//            System.out.println("column name:"+propertyName);
//            System.out.println("column class:"+descriptor.getPropertyType());

			if (map.containsKey(propertyName)) {
				// 下面一句可以 try 起来，这样当一个属性赋值失败的时候就不会影响其他属性赋值。
//				System.out.println("map value:"+ map.get(propertyName));
//				System.out.println("map class type:"+ map.get(propertyName).getClass());
				Object value = map.get(propertyName);
				if (ValueUtil.isNotEmpty(value)) {
					if (descriptor.getPropertyType() != map.get(propertyName).getClass()) {
						continue;
					}

					Object[] args = new Object[1];
//	                System.out.println("classType: "+value.getClass());
	                /*
	                if(descriptor.getPropertyType() == java.util.Date.class){
	                	args[0] = DateUtil.StringToDate(ValueUtil.toStr(value));
	                }else {
	                	args[0] = value;
	                }
	                */

					args[0] = value;
					try {
						descriptor.getWriteMethod().invoke(obj, args);
					} catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException e) {
						e.printStackTrace();
					}
				}
			}
		}
		return obj;
	}

	/**
	 * 将一个 JavaBean 对象转化为一个  Map
	 *
	 * @param bean 要转化的JavaBean 对象
	 * @return 转化出来的  Map 对象
	 * @throws IntrospectionException    如果分析类属性失败
	 * @throws IllegalAccessException    如果实例化 JavaBean 失败
	 * @throws InvocationTargetException 如果调用属性的 setter 方法失败
	 */
	@SuppressWarnings({"rawtypes", "unchecked"})
	public static Map convertBean(Object bean)
			throws IntrospectionException, IllegalAccessException, InvocationTargetException {
		Class type = bean.getClass();
		Map returnMap = new HashMap();
		BeanInfo beanInfo = Introspector.getBeanInfo(type);

		PropertyDescriptor[] propertyDescriptors = beanInfo.getPropertyDescriptors();
		for (int i = 0; i < propertyDescriptors.length; i++) {
			PropertyDescriptor descriptor = propertyDescriptors[i];
			String propertyName = descriptor.getName();
			if (!propertyName.equals("class")) {
				Method readMethod = descriptor.getReadMethod();
				Object result = readMethod.invoke(bean, new Object[0]);
				if (result != null) {
					returnMap.put(propertyName, result);
				} else {
					returnMap.put(propertyName, "");
				}
			}
		}
		return returnMap;
	}

	/**
	 * 将一个 Map 对象转化为一个 JavaBean
	 *
	 * @param obj 要转化的类型
	 * @param map 包含属性值的 map
	 * @return 转化出来的 JavaBean 对象
	 * @throws IntrospectionException    如果分析类属性失败
	 * @throws IllegalAccessException    如果实例化 JavaBean 失败
	 * @throws InstantiationException    如果实例化 JavaBean 失败
	 * @throws InvocationTargetException 如果调用属性的 setter 方法失败
	 */
	@SuppressWarnings({"rawtypes"})
	public static Object mergeObjectMap(Object obj, Map map) throws IntrospectionException {
		BeanInfo beanInfo = Introspector.getBeanInfo(obj.getClass()); // 获取类属性

//        给 JavaBean 对象的属性赋值
		PropertyDescriptor[] propertyDescriptors = beanInfo.getPropertyDescriptors();
		for (int i = 0; i < propertyDescriptors.length; i++) {
			PropertyDescriptor descriptor = propertyDescriptors[i];
			String propertyName = descriptor.getName();
//          System.out.println(propertyName);
			if (map.containsKey(propertyName)) {
//				System.out.println("propertyName: "+propertyName);

				Object value = map.get(propertyName);
				if (ValueUtil.isNotEmpty(value)) {
					if (descriptor.getPropertyType() != map.get(propertyName).getClass()) {
						continue;
					}

					Object[] args = new Object[1];

					if (descriptor.getPropertyType() == java.util.Date.class) {
						args[0] = DateUtil.StringToDate(ValueUtil.toStr(value));
					} else {
						args[0] = value;
					}
//	                System.out.println("value:"+ value);

//	                System.out.println("value class type:"+ value.getClass());
					try {
						descriptor.getWriteMethod().invoke(obj, args);
					} catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException e) {
						e.printStackTrace();
						continue;
					}
				}
			}
		}
		return obj;
	}

	@SuppressWarnings({"rawtypes"})
	public static Object mergeObjectMapExisBigdecimal(Object obj, Map map) throws IntrospectionException {
		BeanInfo beanInfo = Introspector.getBeanInfo(obj.getClass()); // 获取类属性

		// 给 JavaBean 对象的属性赋值
		PropertyDescriptor[] propertyDescriptors = beanInfo.getPropertyDescriptors();
		for (int i = 0; i < propertyDescriptors.length; i++) {
			PropertyDescriptor descriptor = propertyDescriptors[i];
			String propertyName = descriptor.getName();
//           System.out.println(propertyName);
			if (map.containsKey(propertyName)) {
				Object value = map.get(propertyName);
				if (ValueUtil.isNotEmpty(value)) {
					if (descriptor.getPropertyType() != map.get(propertyName).getClass()) {
						continue;
					}

					Object[] args = new Object[1];

					if (descriptor.getPropertyType() == java.util.Date.class) {
						args[0] = DateUtil.StringToDate(ValueUtil.toStr(value));
					} else if (value.getClass() == java.math.BigDecimal.class) {
						args[0] = ValueUtil.toDouble(value);
					} else {
						args[0] = value;
					}
					try {
						descriptor.getWriteMethod().invoke(obj, args);
					} catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException e) {
						e.printStackTrace();
						continue;
					}
				}
			}
		}
		return obj;
	}

	public static String mapToString(Map<String, String[]> paramMap) {
		if (paramMap == null) {
			return "";
		}
		Map<String, Object> params = new HashMap<>(16);
		for (Map.Entry<String, String[]> param : paramMap.entrySet()) {

			String key = param.getKey();
			String paramValue = (param.getValue() != null && param.getValue().length > 0 ? param.getValue()[0] : "");
			String obj = StrUtil.endWithIgnoreCase(param.getKey(), "password") ? "你是看不见我的" : paramValue;
			params.put(key, obj);
		}
		return new Gson().toJson(params);
	}

	public static Object mapToObject(Map<String, Object> map, Class<?> beanClass) throws IllegalAccessException, InstantiationException, InvocationTargetException {
		if (map == null) {
			return null;
		}

		Object obj = beanClass.newInstance();

		ConvertUtils.register(new SqlDateConverter(null), java.sql.Date.class);
		ConvertUtils.register(new DateConverter(null), java.util.Date.class);
		ConvertUtils.register(new SqlTimestampConverter(null), java.sql.Timestamp.class);

		BeanUtils.populate(obj, map);

		return obj;
	}

	public static Map<?, ?> objectToMap(Object obj) {
		if (obj == null) {
			return null;
		}

		return new BeanMap(obj);
	}

	public static Map<String, Object> assemble(Map<String, Object> map) {
		final HashMap<String, Object> resultMap = new HashMap<>();
		if (cn.hutool.core.map.MapUtil.isEmpty(map)) {
			return resultMap;
		}

		for (Entry<String, Object> entry : map.entrySet()) {
			String key = StrUtil.toCamelCase(entry.getKey());
			Object value = entry.getValue();

			resultMap.put(key, value);
		}

		return resultMap;
	}

	public static void main(String[] args) {
//		Map<String, Object> map = new HashMap<>();
//		map.put("my_test", "kkdsafldk");
//		Map<String, Object> newMap = assemble(map);
//		System.out.println(GsonUtil.toString(newMap));

		String str = "[\"http://img.alicdn.com/bao/uploaded/i4/2652292790/O1CN01Mqcjjp1WTrVTrPf9W_!!2652292790.jpg\",\"http://img.alicdn.com/bao/uploaded/i3/2652292790/O1CN01sWXkKZ1WTrVuEifps_!!2652292790.jpg\",\"http://img.alicdn.com/bao/uploaded/i1/2652292790/O1CN01QL38ib1WTrVUtxpIQ_!!2652292790.jpg\",\"http://img.alicdn.com/bao/uploaded/i2/2652292790/O1CN015cn8kt1WTrVxWdKWB_!!2652292790.jpg\",\"http://img.alicdn.com/bao/uploaded/i2/2652292790/O1CN01HXA2Wi1WTrVWA6rRG_!!2652292790.jpg\"]";
		String[] array = str.split(",");
		System.out.println();
	}

}